﻿/**
 * @file DyByteBuff.h
 * @brief dynamic byte buffer
 * $Id: DyByteBuff.h 13 2011-01-01 11:48:27Z tonyjobmails $
 * $Date: 2011-01-01 11:48:27 +0000 (Sat, 01 Jan 2011) $
 * $Author: tonyjobmails $
 * $Revision: 13 $
 */
#ifndef __DY__BYTE__BUFF__H
#define __DY__BYTE__BUFF__H

#include <vector>
#include <assert.h>
#include "Log.h"

/// the unit buffer size
#ifndef _TOTO_DEBUG
static const unsigned int _UNIT_BUFF_SIZE = 1024 * 32;
#else
static const unsigned int _UNIT_BUFF_SIZE = 64;
#endif
/// assert
#define BUFF_ASSERT(cond)	\
	if(!(cond)) log::_ERROR_LOG("[buff error] %s", __PRETTY_FUNCTION__);	\
	assert((cond));
 
/// the define of dynamic byte buffer
class DyByteBuff
{
	public:
		DyByteBuff() : _M_rd_ptr(0), _M_wr_ptr(0), _M_size(0) {};
		~DyByteBuff() {};
		
	public:
		/// write the data into the buffer
		void write(const unsigned char *_data, const unsigned int _size);
		
		/// check the space or allocate the buffer
		void prewrite(const unsigned int _size);
		
		/// get the write addr of the buffer
		unsigned char* wr_ptr();
		
		/// get the read addr of the buffer
		unsigned char* rd_ptr();
		
		/// get the size of data
		unsigned int rd_size();
		/// get the residua space of the buffer
		unsigned int wr_size();
		
		/// arrange the buffer after reading
		void rd_shiftout(const unsigned int _size);
		/// arrange the buffer after writing
		void wr_shiftout(const unsigned int _size);
		
	private:
		/// arrange the buffer
		void shiftout(const unsigned int _rd_size, const unsigned int _wr_size);
		
#ifdef _TOTO_DEBUG
	public:
		void disp()
		{
			log::_DEBUG_LOG("_M_size(%u), _M_wr_ptr(%u), _M_rd_ptr(%u)",
					_M_size, _M_wr_ptr, _M_rd_ptr);
		}
#endif
	private:
		std::vector<unsigned char> _M_buffer;		/// buffer
		unsigned int _M_rd_ptr;				/// read ptr of the buffer
		unsigned int _M_wr_ptr;				/// write ptr of the buffer
		unsigned int _M_size;				/// the size of buffer
};
 
#endif	/// __DY__BYTE__BUFF__H

